﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.Net;
using System.IO;
using System.Web;
using System.Security.Cryptography.X509Certificates;
using System.Net.Security;
using Common;
using Common.Protocol;

namespace PPTControl
{
    public class HTTPProxy : IProxy
    {
        
        public string DebugServer
        {
            get;set;
        }
        public const int USE_DEFAULT_TIMEOUT = -1;
        public const string URL_BASE = "http://localhost:31103/";
        public const string URL_LOGIN = URL_BASE + "Login.aspx";
        public const string URL_CHECKREQUEST = URL_BASE + "PPTCheckRequest.aspx";
        public const string URL_RESPONSE = URL_BASE + "PPTResponse.aspx";

        public const int RESPONSE_TIMEOUT = 10 * 1000; // 10 SECONDS
        public const int CHECKREQ_TIMEOUT = 20 * 60 * 1000;//20 MINUTES

        private List<HttpWebRequest> _pendingRequestList;
        private Cookie _co = null;
        private CookieContainer _cc = new CookieContainer();

        public HTTPProxy()
        {
            ServicePointManager.ServerCertificateValidationCallback = ValidateServerCertificate;
            _pendingRequestList = new List<HttpWebRequest>();
        }

        /// <summary>
        /// Implement of IProxy functions
        /// </summary>
        public void Init()
        {
        }

        public bool Connect()
        {
            return true;
        }

        public void Deinit()
        {
            AbortPendingRequests();
        }

        public LoginResp Login(LoginReq loginReq)
        {
            String requestStr = loginReq.ToJson();
            string url = URL_LOGIN;
            if(DebugServer!=null)
            {
                url = DebugServer + "/Login.aspx";
            }
            String controlCmd = post(url, UTF8Encoding.UTF8.GetBytes(requestStr), null, RESPONSE_TIMEOUT);
            if (String.IsNullOrEmpty(controlCmd))
            {
                throw new Exception("network error!");
            }

            LoginResp respCmd = Command.FromJson<LoginResp>(controlCmd);
            return respCmd;
        }

        public CheckResp CheckCommand(CheckReq checkReq)
        {
            String requestStr = checkReq.ToJson();
            string url = URL_CHECKREQUEST;
            if (DebugServer != null)
            {
                url = DebugServer + "/PPTCheckRequest.aspx";
            }
            String controlCmd = post(url, UTF8Encoding.UTF8.GetBytes(requestStr), null, CHECKREQ_TIMEOUT);
            if (String.IsNullOrEmpty(controlCmd))
            {
                throw new Exception("network error!");
            }
            CheckResp respCmd = Command.FromJson<CheckResp>(controlCmd);
            return respCmd;
        }

        public void ResponseCommand(ControlResp controlResp)
        {
            String responseStr = controlResp.ToJson();
            string url = URL_RESPONSE;
            if (DebugServer != null)
            {
                url = DebugServer + "/PPTResponse.aspx";
            }
            post(url, UTF8Encoding.UTF8.GetBytes(responseStr), null, RESPONSE_TIMEOUT);
        }

        private bool ValidateServerCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
        {
            return true;
        }
       
        public string post(string str, byte[] body, WebHeaderCollection headers,int timeout)
        {
            try
            {

                Uri ul = new Uri(str);
                HttpWebRequest request = WebRequest.Create(ul) as HttpWebRequest;
                request.CookieContainer = _cc;
                if (headers != null)
                {
                    request.Headers.Add(headers);
                }


                if (timeout != USE_DEFAULT_TIMEOUT)
                {
                    request.Timeout = timeout;
                }
                request.Method = "POST";
                request.ContentType = "application/x-www-form-urlencoded";
                request.ContentLength = body.Length;
                //request.UserAgent = "push-sn";
                //SetCookies(request);
                AddPendingRequest(request);
                request.GetRequestStream().Write(body, 0, body.Length);

                HttpWebResponse response = (HttpWebResponse)request.GetResponse();
                string respStr= Util.returnResponsebody(response.GetResponseStream());
                response.Close();
                RemovePendingRequest(request);
                return respStr;


           }
  
        
            catch (Exception ex)
            {

                return "";
            }

            return "";
        }

        public void AbortPendingRequests()
        {
            lock (_pendingRequestList)
            {
                foreach (HttpWebRequest req in _pendingRequestList)
                {
                    req.Abort();
                }
                _pendingRequestList.Clear();
            }
        }

        void AddPendingRequest(HttpWebRequest req)
        {
            lock (_pendingRequestList)
            {
                _pendingRequestList.Add(req);
            }
        }

        void RemovePendingRequest(HttpWebRequest req)
        {
            lock (_pendingRequestList)
            {
                _pendingRequestList.Remove(req);
            }
        }

        private void SetCookies(HttpWebRequest request)
        {
            if (_co != null)
                if (request.CookieContainer != null)
                {
                    request.CookieContainer.Add(_co);
                }
                else
                {
                    request.CookieContainer = new CookieContainer();
                    _co.Path = "/";

                    request.CookieContainer.Add(_co);
                }
        }

    }     

      

}
